# ---------------------------------------------------------------------------
# Desc:   PowerShell Community Extensions miscellaneous function definitions.
# Site:   http://www.codeplex.com/PowerShellCX
# Usage:  In your profile place the following command:
#  
#         . "$Env:PscxHome\Profile\GenericFunctions.ps1"
# ---------------------------------------------------------------------------

# ---------------------------------------------------------------------------
# Name:   Add-PathVariable
# Alias:  gvs
# Author: Jachym
# Desc:   This function adds the specified paths to the specified environment
#         variable.
#        
# Usage:  apv Path C:\Bin
#         Add-PathVariable Path C:\Bin,C:\Users\John\Bin
# ---------------------------------------------------------------------------
Set-Alias apv Add-PathVariable -Option AllScope -Description "PSCX function alias"
function Add-PathVariable($Variable, $Values) {
	if (test-path "Env:\$Variable") {
		$paths = (get-item "Env:\$Variable").Value.Split(';')
	}

	$newvar = @($paths + $values) | Select-Object -Unique

	$ofs = ';'
	set-item "Env:\$Variable" "$newvar"
}

# ---------------------------------------------------------------------------
# Name:   Get-VariableSorted
# Alias:  gvs
# Author: Keith Hill
# Desc:   This function displays your PoSH variables sorted by name.  It
#         seems like that should be the default.  Oh well.
#        
# Usage:  gvs
#         Get-VariableSorted
# ---------------------------------------------------------------------------
Set-Alias gvs Get-VariableSorted -Option AllScope -Description "PSCX function alias"
function Get-VariableSorted 
{ 
	Get-Variable | Sort Name 
}

# ---------------------------------------------------------------------------
# Name:   Get-PscxVariable
# Alias:  gvpscx
# Author: Keith Hill
# Desc:   This function displays the variables defined by PSCX.
# ---------------------------------------------------------------------------
Set-Alias gvpscx Get-PscxVariable -Option AllScope -Description "PSCX function alias"
function Get-PscxVariable
{
	Get-Variable | Where {$_.Description -match "^PSCX"}
}

# ---------------------------------------------------------------------------
# Name:   Get-PscxAlias
# Alias:  galpscx
# Author: Keith Hill
# Desc:   This function displays all of the aliases created by PSCX.
# ---------------------------------------------------------------------------
Set-Alias galpscx Get-PscxAlias -Option AllScope -Description "PSCX function alias"
function Get-PscxAlias 
{
	Get-Alias | Where {$_.Description -match "^PSCX" -or $_.Name -match "Pscx|__pscx"}
}

# ---------------------------------------------------------------------------
# Name:   Get-PscxCmdlet
# Alias:  gcmpscx
# Author: Keith Hill
# Desc:   This function displays all of the cmdlets provided by PSCX.
# ---------------------------------------------------------------------------
Set-Alias gcmpscx Get-PscxCmdlet -Option AllScope -Description "PSCX function alias"
function Get-PscxCmdlet
{
	Get-Command -type cmdlet | Where {$_.PSSnapin -match "^Pscx"}
}

# ---------------------------------------------------------------------------
# Name:   Get-HelpMatch 
# Alias:  ghm, apropos
# Author: Lee Holmes, modified by Keith Hill to add aliases and -verbose param
#         Used with permission from Lee Holmes - http://www.leeholmes.com/blog
# Desc:   Search the PowerShell help documentation for a given keyword or 
#         regular expression.
# Usage:
#
#    Get-HelpMatch hashtable
#    Get-HelpMatch "(datetime|ticks)" -verbose
# ---------------------------------------------------------------------------
Set-Alias ghm Get-HelpMatch -Option AllScope -Description "PSCX function alias"
Set-Alias apropos Get-HelpMatch -Option AllScope -Description "PSCX function alias"
function Get-HelpMatch 
{
    param($searchWord = $(throw "Please specify content to search for"),
         [switch]$verbose = $false)
         
    $helpNames = $(get-help *)
    foreach($helpTopic in $helpNames) {
        $content = get-help -Full $helpTopic.Name | Out-String
        if($content -match $searchWord) {
            $helpTopic | select Name,Synopsis
            if ($verbose) {
                $content | %{$_.Split([System.Environment]::NewLine)} |
                    Select-String $searchWord | %{"    $($_.Line.Trim())"}
            }
        }
    }
}

# ---------------------------------------------------------------------------
# Name:   Get-Random
# Author: Jachym
# Desc:   This function returns a random number.
# ---------------------------------------------------------------------------
Set-Alias rnd Get-Random -Option AllScope -Description "PSCX function alias"
Set-Variable Random (new-object Random) -Scope global -Option ReadOnly -Description "PSCX variable"

function Get-Random {
	$Random.NextDouble()
}

# ---------------------------------------------------------------------------
# Name:   Get-Url
# Author: Keith Hill
# Desc:   This function scrapes the supplied web URL and outputs a string
#         containing the contents of the web page.
#        
# Usage:  Get-Url http://www.codeplex.com/PowerShellCX
# ---------------------------------------------------------------------------
function Get-Url([string]$url) {
    $webClient = new-object System.Net.WebClient
    $webClient.DownloadString($url)
}

# ---------------------------------------------------------------------------
# Name:   Import-Assembly
# Author: Keith Hill
# Desc:   This function loads the specified assembly via LoadWithPartialName.
#        
# Usage:  Import-Assembly System.Windows.Forms
# ---------------------------------------------------------------------------
function Import-Assembly([string]$assemblyFriendlyName) {
	$assembly = [System.Reflection.Assembly]::LoadWithPartialName($assemblyFriendlyName)
	if ($assembly -eq $null) {
		Write-Error "Failed to import assembly by the name $assemblyFriendlyName"
	}
	$assembly
}

# ---------------------------------------------------------------------------
# Name:   Import-AssemblyFrom
# Author: Keith Hill
# Desc:   This function loads the specified assembly via LoadFrom.
#        
# ---------------------------------------------------------------------------
function Import-AssemblyFrom([string]$path) {
    $rpath = Resolve-Path $path
	$assembly = [System.Reflection.Assembly]::LoadFrom($rpath)
	if ($assembly -eq $null) {
		Write-Error "Failed to import assembly from $rpath"
	}
	$assembly
}

# ---------------------------------------------------------------------------
# Name:   Edit-File
# Alias:  e
# Author: Keith Hill
# Desc:   Opens up the specified text file in the text editor specified by 
#         $PscxTextEditorPreference variable.  If not specified or the 
#         specified editor isn't found then notepad is used.
#        
# Usage:  e foo.txt
#         Edit-File foo.txt
# ---------------------------------------------------------------------------
Set-Alias e Edit-File -Option AllScope -Description "PSCX function alias"
function Edit-File([string]$path)
{
	$editor = "notepad.exe"
	if ($PscxTextEditorPreference -ne $null -and $PscxTextEditorPreference.Length -gt 0)
	{
		Get-Command $PscxTextEditorPreference 2>&1 | out-null
		if ($?) {
			$editor = $PscxTextEditorPreference
		}
	}
	
	& $editor $path
}

# ---------------------------------------------------------------------------
# Name:   Edit-Profile, Edit-HostProfile, Edit-GlobalProfile Edit-GlobalHostProfile
# Alias:  ep, ehp, egp, eghp
# Author: Keith Hill
# Desc:   These functions allow you to easily open up in your favorite text 
#         editor using the previously defined Edit-File function.
# ---------------------------------------------------------------------------
Set-Alias egp Edit-GlobalProfile -Option AllScope -Description "PSCX function alias"
function Edit-GlobalProfile {
	Edit-File (Join-Path $PSHome Profile.ps1)
}

Set-Alias eghp Edit-GlobalHostProfile -Option AllScope -Description "PSCX function alias"
function Edit-GlobalHostProfile {
	$HostProfileFilename = Split-Path $Profile -Leaf
	Edit-File (Join-Path $PSHome $HostProfileFilename)
}

Set-Alias ep Edit-Profile -Option AllScope -Description "PSCX function alias"
function Edit-Profile {
	$ProfileDir = Split-Path $Profile -Parent
	Edit-File (Join-Path $ProfileDir Profile.ps1)
}

Set-Alias ehp Edit-HostProfile -Option AllScope -Description "PSCX function alias"
function Edit-HostProfile {
	Edit-File $Profile
}

# ---------------------------------------------------------------------------
# Name:   Resolve-Error
# Alias:  rver
# Author: Original - Jeffrey Snover, added here by Keith Hill
# Desc:   Use when reporting an error or ask a question about a exception you
#         are seeing.  This function provides all the information we have 
#         about the error message making it easier to diagnose what is 
#         actually going on.
# ---------------------------------------------------------------------------
Set-Alias rver Resolve-Error -Option AllScope -Description "PSCX function alias"
function Resolve-Error ($ErrorRecord=$Error[0])
{
   $ErrorRecord | Format-List * -Force
   $ErrorRecord.InvocationInfo |Format-List *
   $Exception = $ErrorRecord.Exception
   for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException))
   {   "$i" * 80
       $Exception |Format-List * -Force
   }
}